//
//  UIImage+Extension.swift
//  AIPhotoProcess
//
//  Created by aw031 on 17/10/2025.
//

import Foundation
import Accelerate
import Kingfisher
import MobileCoreServices
import UniformTypeIdentifiers


// 获取图片（始终使用原始渲染模式）
/// - Parameter name: 图片名称
/// - Returns: UIImage 对象
func KImage(_ name: String) -> UIImage? {
    return UIImage(named: name)?.withRenderingMode(.alwaysOriginal)
}


//func KImageNoCache(_ name: String) -> UIImage? {
//    let path = Bundle.main.path(forResource: name, ofType: "png") ?? ""
//    return image = UIImage(contentsOfFile: path)?.withRenderingMode(.alwaysOriginal)
//}

extension UIImage {
    
    
    func directionCorrection() -> UIImage {
        if self.imageOrientation == .up {
            return self
        }
        
        var transform = CGAffineTransform.identity
        
        switch self.imageOrientation {
        case .down, .downMirrored:
            transform = transform.translatedBy(x: self.size.width, y: self.size.height)
            transform = transform.rotated(by: .pi)
            
        case .left, .leftMirrored:
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.rotated(by: .pi / 2)
            
        case .right, .rightMirrored:
            transform = transform.translatedBy(x: 0, y: self.size.height)
            transform = transform.rotated(by: -.pi / 2)
            
        case .up, .upMirrored:
            break
            
        @unknown default:
            break
        }
        
        switch self.imageOrientation {
        case .upMirrored, .downMirrored:
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
            
        case .leftMirrored, .rightMirrored:
            transform = transform.translatedBy(x: self.size.height, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
            
        case .up, .down, .left, .right:
            break
            
        @unknown default:
            break
        }
        
        guard let cgImage = self.cgImage,
              let colorSpace = cgImage.colorSpace else {
            return self
        }
        
        let ctx = CGContext(data: nil,
                            width: Int(self.size.width),
                            height: Int(self.size.height),
                            bitsPerComponent: cgImage.bitsPerComponent,
                            bytesPerRow: 0,
                            space: colorSpace,
                            bitmapInfo: cgImage.bitmapInfo.rawValue)
        
        ctx?.concatenate(transform)
        
        switch self.imageOrientation {
        case .left, .leftMirrored, .right, .rightMirrored:
            ctx?.draw(cgImage, in: CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width))
            
        default:
            ctx?.draw(cgImage, in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        }
        
        guard let cgimg = ctx?.makeImage() else {
            return self
        }
        
        return UIImage(cgImage: cgimg)
    }
    
    /// 纯色图片
    @objc static func image(with color: UIColor) -> UIImage? {
        var alpha: CGFloat = 0
        color.getRed(nil, green: nil, blue: nil, alpha: &alpha)
        let opaque = (alpha == 1.0)
        let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
        UIGraphicsBeginImageContextWithOptions(rect.size, opaque, UIScreen.main.scale)
        color.setFill()
        UIRectFill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    
    
    /// 渐变色图片
    static func imageGrandientLayer(with size: CGSize, cornerRadius: CGFloat) -> UIImage? {
        // 需补充 GradualDirectionType 枚举和 CALayer.ConfigGradientLayerWithSize 方法

        return UIImage.imageGrandientLayer(with: [ColorD0CDF7,ColorF7DCFC], directionType: .topToBottom, size: size, cornerRadius: cornerRadius)
    }
    
    /// 渐变色图片
    static func imageGrandientLayer(with size: CGSize, directionType: GradualDirectionType = .topToBottom, cornerRadius: CGFloat) -> UIImage? {
        // 需补充 GradualDirectionType 枚举和 CALayer.ConfigGradientLayerWithSize 方法

        return UIImage.imageGrandientLayer(with: [ColorD0CDF7,ColorF7DCFC], directionType: .topToBottom, size: size, cornerRadius: cornerRadius)
    }
    
    
    /// 渐变色图片（需补充 GradualDirectionType 及 CALayer 扩展）
    static func imageGrandientLayer(with colors: [UIColor], directionType: GradualDirectionType, size: CGSize, cornerRadius: CGFloat) -> UIImage? {
        // 需补充 GradualDirectionType 枚举和 CALayer.ConfigGradientLayerWithSize 方法
        if (CGSizeEqualToSize(size, CGSize.zero)) {
            return nil;
        }
        let gradientLayer = CAGradientLayer.initGradientLayer(size: size, gradientColors: colors, directionType: directionType);
        let img = UIImage.configGradientImage(with: size, gradientLayer: gradientLayer, cornerRadius: cornerRadius)
        return img
    }
    
    /// 通过 CAGradientLayer 生成渐变图片
    /// - Parameters:
    ///   - imageSize: 图片尺寸
    ///   - gradientLayer: 渐变图层
    ///   - cornerRadius: 圆角半径
    /// - Returns: 生成的渐变图片
    @objc static func configGradientImage(with imageSize: CGSize,
                                          gradientLayer: CAGradientLayer,
                                          cornerRadius: CGFloat) -> UIImage? {
        // 开始图像上下文
        UIGraphicsBeginImageContextWithOptions(imageSize, false, 0)
        guard let context = UIGraphicsGetCurrentContext() else {
            UIGraphicsEndImageContext()
            return nil
        }
        
        // 设置圆角矩形路径
        let rect = CGRect(origin: .zero, size: imageSize)
        if cornerRadius > 0 {
            let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
            context.addPath(path.cgPath)
            context.clip()
        }
        
        // 在上下文中渲染渐变层
        gradientLayer.render(in: context)
        
        // 获取生成的图片
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return image
    }
    
    
    /// 按目标尺寸拉伸图片（填充）
    func scaleToFill(size: CGSize) -> UIImage? {
        if self.size == size { return self }
        UIGraphicsBeginImageContextWithOptions(size, false, self.scale)
        self.draw(in: CGRect(origin: .zero, size: size))
        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return scaledImage
    }
    
    /// 按目标尺寸等比缩放图片（适应）
    func scaleToFit(size: CGSize) -> UIImage? {
        if self.size == size { return self }
        let widthRatio = size.width / self.size.width
        let heightRatio = size.height / self.size.height
        let scaleRatio = min(widthRatio, heightRatio)
        let scaledSize = CGSize(width: self.size.width * scaleRatio, height: self.size.height * scaleRatio)
        if scaledSize.width <= 0 || scaledSize.height <= 0 { return nil }
        UIGraphicsBeginImageContextWithOptions(scaledSize, false, 0.0)
        self.draw(in: CGRect(origin: .zero, size: scaledSize))
        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return scaledImage
    }
    
    //    func compressionQuality05() -> Data? {
    //        return self.jpegData(compressionQuality: 0.5)
    //    }
    
//    func AndCompressionQuality05() -> (imageData : Data?, fitImage : UIImage?) {
//        
//        if let fitImg = self.scaleToFit(size: KKeyboardSize) {
//            
//            if let quality05Image = fitImg.kf.pngRepresentation() {
//                return (quality05Image,fitImg)
//            }else {
//                return (nil,nil)
//            }
//            
//        }else {
//            if let quality05Image = self.kf.pngRepresentation() {
//                return (quality05Image,self)
//            }else {
//                return (nil,nil)
//            }
//        }
//    }
            
    /// 判断图片是否为空
    static func isImageEmpty(_ image: UIImage?) -> Bool {
        guard let image = image else { return true }
        if image.cgImage == nil { return true }
        if image.size == .zero { return true }
        return false
    }
    
    /// 复制图片到粘贴板（自动处理GIF）
    static func copyImage(_ data: Data?) -> Bool {
        if let imageData = data {
            UIPasteboard.general.setData(imageData, forPasteboardType: UTType.gif.identifier )
            return true
        }else {
            return false
        }
    }
 
}

//MARK: -- 修改

extension UIImage {
    
    private static func generate(color: UIColor) -> CIImage {
        let parameters = [kCIInputColorKey: CIColor(cgColor: color.cgColor)]
        guard let filter = CIFilter(name: "CIConstantColorGenerator", parameters: parameters) else {
            fatalError("无法创建 CIFilter: CIConstantColorGenerator")
        }
        guard let outputImage = filter.outputImage else {
            fatalError("CIConstantColorGenerator 没有输出图像")
        }
        return outputImage
    }
    
    private static func compositeSourceOver(overlay: CIImage, background: CIImage) -> CIImage {
        let parameters = [
            kCIInputBackgroundImageKey: background,
            kCIInputImageKey: overlay
        ]
        guard let filter = CIFilter(name: "CISourceOverCompositing", parameters: parameters) else {
            fatalError("无法创建 CIFilter: CISourceOverCompositing")
        }
        guard let outputImage = filter.outputImage else {
            fatalError("CISourceOverCompositing 没有输出图像")
        }
        return outputImage.cropped(to: background.extent)
    }
    
    private static func overlay(color: UIColor, on image: CIImage) -> CIImage {
        let overlayImage = generate(color: color).cropped(to: image.extent)
        return compositeSourceOver(overlay: overlayImage, background: image)
    }
    
    // 修改后的 adjustDarkness 函数
    private static  func adjustDarkness(darkness: Float, on image: CIImage) -> CIImage {
        // 限制 darkness 值在 0 到 1 之间
        let darknessValue = min(max(darkness, 0), 1)
        // 创建一个黑色叠加层，透明度根据 darknessValue 变化
        let color = UIColor(white: 0, alpha: CGFloat(darknessValue))
        // 使用之前定义的 overlay 函数进行叠加
        return overlay(color: color, on: image)
    }
    //MARK: -- 调整暗度
    private static func updateImageWithDarkness(currentImage : UIImage , darkness: Float , context : CIContext) -> UIImage {
        let ciImage = CIImage(image: currentImage)!
        let outputCIImage =  adjustDarkness(darkness: darkness, on: ciImage)
        // 转换回 UIImage
        let cgImage = context.createCGImage(outputCIImage, from: outputCIImage.extent)!
        let processedImage = UIImage(cgImage: cgImage)
        return processedImage
    }
    
    
    // MARK: - 使用 vImage 进行模糊处理
    private static func applyVImageBlur(to image: UIImage, blurLevel: Float) -> UIImage? {
        let blurLevel = blurLevel.clamped(to: 0...1)
        var boxSize = Int(blurLevel * 100)
        boxSize = boxSize - (boxSize % 2) + 1
        
        guard let cgImage = image.cgImage else { return nil }
        
        // 1. 确保正确的颜色空间和格式
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let bitmapInfo = CGBitmapInfo.byteOrder32Big.rawValue | CGImageAlphaInfo.premultipliedLast.rawValue
        
        // 2. 创建正确对齐的缓冲区
        let width = cgImage.width
        let height = cgImage.height
        let bytesPerPixel = 4
        let bitsPerComponent = 8
        
        // 计算正确的bytesPerRow（确保是16的倍数，满足vImage要求）
        var bytesPerRow = width * bytesPerPixel
        bytesPerRow = (bytesPerRow + 15) & ~15 // 对齐到16字节边界
        
        // 3. 创建临时缓冲区
        guard let pixelBuffer = malloc(bytesPerRow * height) else {
            KLog("Failed to allocate pixel buffer")
            return nil
        }
        defer { free(pixelBuffer) }
        
        // 4. 创建CGContext重绘图像，确保正确格式
        guard let context = CGContext(
            data: pixelBuffer,
            width: width,
            height: height,
            bitsPerComponent: bitsPerComponent,
            bytesPerRow: bytesPerRow,
            space: colorSpace,
            bitmapInfo: bitmapInfo
        ) else {
            KLog("Failed to create CGContext")
            return nil
        }
        
        context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
        
        // 5. 设置vImage缓冲区
        var inBuffer = vImage_Buffer(
            data: pixelBuffer,
            height: vImagePixelCount(height),
            width: vImagePixelCount(width),
            rowBytes: bytesPerRow
        )
        
        var outBuffer = vImage_Buffer()
        guard malloc(Int(bytesPerRow * height)) != nil else {
            KLog("Failed to allocate output buffer")
            return nil
        }
        outBuffer.data = malloc(Int(bytesPerRow * height))
        outBuffer.width = vImagePixelCount(width)
        outBuffer.height = vImagePixelCount(height)
        outBuffer.rowBytes = bytesPerRow
        defer { free(outBuffer.data) }
        
        // 6. 应用模糊
        let error = vImageBoxConvolve_ARGB8888(
            &inBuffer,
            &outBuffer,
            nil,
            0, 0,
            UInt32(boxSize),
            UInt32(boxSize),
            nil,
            vImage_Flags(kvImageEdgeExtend)
        )
        
        if error != kvImageNoError {
            KLog("Error from convolution: \(error)")
            return nil
        }
        
        // 7. 创建结果图像
        guard let resultContext = CGContext(
            data: outBuffer.data,
            width: width,
            height: height,
            bitsPerComponent: bitsPerComponent,
            bytesPerRow: bytesPerRow,
            space: colorSpace,
            bitmapInfo: bitmapInfo
        ), let resultImage = resultContext.makeImage() else {
            return nil
        }
        
        return UIImage(cgImage: resultImage)
    }
    
    //MARK: -- 模糊 + 调整暗度
    func blurryImage(_ blurLevel: Float, darkness: Float , context : CIContext) -> UIImage? {
        // 1. 先模糊图片（使用 Accelerate）
        guard let blurredImage = UIImage.applyVImageBlur(to: self, blurLevel: blurLevel) else {
            return nil
        }
        // 2. 再调整暗度（使用 CoreImage）
        return UIImage.updateImageWithDarkness(currentImage: blurredImage, darkness: darkness, context: context)
    }
    
    
    //MARK: -- 模糊 + 调整暗度
    static func blurryImage(_ image: UIImage, withBlurLevel blur: Float, darkness: Float , context : CIContext) -> UIImage? {
        // 1. 先模糊图片（使用 Accelerate）
        guard let blurredImage = applyVImageBlur(to: image, blurLevel: blur) else {
            return nil
        }
        // 2. 再调整暗度（使用 CoreImage）
        return UIImage.updateImageWithDarkness(currentImage: blurredImage, darkness: darkness, context: context)
    }
    
    func getTopLeftColor(rectSize: CGSize = CGSize(width: 50, height: 50)) -> UIColor? {
        guard let cgImage = self.cgImage else { return nil }
        
        // 计算左上角区域
        let rect = CGRect(x: 0, y: 0, width: min(rectSize.width, self.size.width),
                          height: min(rectSize.height, self.size.height))
        
        // 创建位图上下文
        guard let context = CGContext(data: nil,
                                      width: Int(rect.width),
                                      height: Int(rect.height),
                                      bitsPerComponent: 8,
                                      bytesPerRow: 4 * Int(rect.width),
                                      space: CGColorSpaceCreateDeviceRGB(),
                                      bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else { return nil }
        
        // 绘制指定区域
        context.draw(cgImage, in: CGRect(x: -rect.origin.x, y: -rect.origin.y,
                                         width: CGFloat(cgImage.width), height: CGFloat(cgImage.height)))
        
        // 获取左上角像素颜色
        guard let pixelData = context.data else { return nil }
        let data = UnsafePointer<UInt8>(pixelData.assumingMemoryBound(to: UInt8.self))
        
        let pixelInfo = 4 * (Int(rect.width) * Int(rect.height/2) + Int(rect.width/2))
        
        let r = CGFloat(data[pixelInfo]) / 255.0
        let g = CGFloat(data[pixelInfo+1]) / 255.0
        let b = CGFloat(data[pixelInfo+2]) / 255.0
        let a = CGFloat(data[pixelInfo+3]) / 255.0
        
        return UIColor(red: r, green: g, blue: b, alpha: a)
    }
    
}

// MARK: - 辅助扩展：限制数值范围
extension Comparable {
    func clamped(to limits: ClosedRange<Self>) -> Self {
        return min(max(self, limits.lowerBound), limits.upperBound)
    }
}
